package pri.zjy.matrix;

import java.util.ArrayList;
import java.util.List;

/**
 * @author zhangjy
 * @description 螺旋矩阵
 * <p>
 * 给你一个 m 行 n 列的矩阵 matrix ，请按照 顺时针螺旋顺序 ，返回矩阵中的所有元素。
 * @date 2025/6/12 18:10
 */
public class SpiralOrder_54 {

    /**
     * 参考官解：按层模拟
     */
    public List<Integer> spiralOrder(int[][] matrix) {
        if (matrix == null) return null;

        List<Integer> ans = new ArrayList<>();
        int rows = matrix.length, columns = matrix[0].length;
        int  top = 0, bottom = rows - 1, left = 0, right = columns - 1;
        // 按层旋转
        while (left <= right && top <= bottom) {
            // 1.上 -> 右  [top, l] -> [top, r]
            // 行不动,列增加 (记录最后一列)
            for (int i = left; i <= right; i++) {
                ans.add(matrix[top][i]);
            }
            // 2.右 -> 下 [top+1, r] -> [bottom, r]
            // 行增加,列不动
            for (int i = top + 1; i <= bottom; i++) {
                ans.add(matrix[i][right]);
            }

            // 防止 行或列不足一格 时重复添加或越界
            // 如果只剩下一行（top == bottom），此时不能再执行下→左（因为当前 top 与 bottom 相等，说明下面那一圈已经不是矩形了）；
            // 如果只剩下一列（left == right），不能再执行左→上（因为再遍历会和上→右、右→下重叠）；
            if (left < right && top < bottom) {
                // 3.下 -> 左 [bottom, r-1] -> [bottom, l]
                // 行不动,列减少
                for (int i = right - 1; i >= left; i--) {
                    ans.add(matrix[bottom][i]);
                }

                // 4.左 -> 上 [bottom-1, r-1] -> [top+1, l]
                // 行减少,列不动 [bo]
                for (int i = bottom - 1; i > top; i--) {
                    ans.add(matrix[i][left]);
                }
            }

            // 5.
            // 更新left right top bottom, 从而开启下一层
            left++;
            right--;
            top++;
            bottom--;
        }

        return ans;
    }

}
